package org.act.BPEL2Automata.graphics;

import java.awt.Point;
import java.util.LinkedList;

import org.act.BPEL2Automata.automata.AutomataImp;
import org.act.BPEL2Automata.automata.module.State;
import org.act.BPEL2Automata.graphics.model.Automaton;
import org.act.BPEL2Automata.graphics.model.State4G;
import org.act.BPEL2Automata.graphics.model.TransitionRule;
import org.act.BPEL2Automata.automata.module.StatePair;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.widgets.Display;

/**
 * This class convert generated an AutomataImp object 
 * to an Automaton object.
 * 
 * @author baoxiwu<bb@feijiao.info>,ACT,Beihang University
 * @version 0.9.0
 * @since 2010-05-18
 * 
 */
public class Convertor {
	/**
	 * It converts <b>AutomataImp</b> objects to <b>Automaton</b> objects which 
	 * can be used to draw graphs by <b>GraphPainterFactory</b>.
	 * @param automata
	 * @return automaton
	 */
	public static Automaton convert(AutomataImp automata){
		Automaton automaton = new Automaton();
		State4G s = null;
		TransitionRule tr = null;
		
		//generate states
		for(int i = 0; i < automata.getStateSet().size(); i++){
			State tmp = automata.getStateSet().get(i);
			
			//non final state or start state
			//These are majority.
			if(!(automata.getFinalStateSet().contains(tmp)) 
					&& automata.getStartState() != tmp){
				s = new State4G(tmp.getID(),State4G.STATE4G_TYPE_OTHER,tmp);
				automaton.addState(s);
			}
			//final state
			else
			if(automata.getFinalStateSet().contains(tmp)){
				s = new State4G(tmp.getID(),State4G.STATE4G_TYPE_FINAL,tmp);
				automaton.addState(s);
			}
			//start state
			else
			if(automata.getStartState() == tmp){
				s = new State4G(tmp.getID(),State4G.STATE4G_TYPE_START,tmp);
				automaton.addState(s);
			}
			
			s.setPoint(new Point(0,0));
		}
		
		//generate transition rules.
		for(int i = 0; i < automata.getTransitionFunction().getTransitionRuleList().size(); i++){
			org.act.BPEL2Automata.automata.module.TransitionRule tmp = automata.getTransitionFunction().getTransitionRuleList().get(i);
			tr = new TransitionRule();
			
			tr.setMessage(tmp.getMessage());
			
			for(int j = 0; j < automaton.getStateSet().size(); j++){
				if(tmp.getStartState() == automaton.getStateSet().get(j).getFrom()){
					tr.setStartState(automaton.getStateSet().get(j));
				}
				if(tmp.getEndState() == automaton.getStateSet().get(j).getFrom()){
					tr.setEndState(automaton.getStateSet().get(j));
				}
			}
			
			automaton.addTransitionRule(tr);
		}
		
		return automaton;
	}
	
	
	//TODO remove
	/**
	 * add color to <b>StatePair</b>s.
	 * @param sp
	 */
	public static void addColor(LinkedList<StatePair> sp){
		LinkedList<Color> colors = new LinkedList<Color>();
		Color color = null;
		//graph's default color:black
		colors.add(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
		
		for(int i = 0; i < sp.size(); i++){
				color = Convertor.getRandomColor(colors);
				sp.get(i).setColor(color);
				
				colors.add(color);
		}
	}
	
	/**
	 * randomly generate an unique color which is not in <b>colors</b>. 
	 * @param colors
	 * @return
	 */
	public static Color getRandomColor(LinkedList<Color> colors){
		boolean exist = false;
		
		while(true){
			int a = (int)(Math.random()*255);
			int b = (int)(Math.random()*255);
			int c = (int)(Math.random()*255);
			
			Device device = Display.getCurrent();
			
			Color color = new Color (device, a, b, c);
			
			for(int i = 0; i < colors.size(); i++){
				if(color.equals(colors.get(i))){
					exist = true;
					break;
				}
			}
			
			if(exist){
				exist = false;
				continue;
			}
			else{
				return color;
			}
		}
		
	}
}
